package com.tuananh.radnom.model.protocol.upnp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.teleal.cling.UpnpService;
import org.teleal.cling.UpnpServiceImpl;
import org.teleal.cling.model.message.header.STAllHeader;
import org.teleal.cling.model.meta.LocalDevice;
import org.teleal.cling.model.meta.RemoteDevice;
import org.teleal.cling.registry.Registry;
import org.teleal.cling.registry.RegistryListener;

import com.tuananh.radnom.model.discovery.DiscoverNetInt;
import com.tuananh.radnom.model.protocol.service.PassiveDiscover;

@XmlDiscriminatorValue("PassiveUpnp")
public class PassiveUpnp extends PassiveDiscover {
	void putToHashMap(Map map, Object key, Object value) {
		if (value != null)
			map.put(key, value);
	}

	DiscoverNetInt generate(RemoteDevice device) {
		DiscoverNetInt discovered = new DiscoverNetInt();
		discovered.setNodeName(device.getDetails().getFriendlyName());
		discovered.setIp(device.getRoot().getIdentity().getDescriptorURL()
				.getHost());

		if (device.getRoot().getIdentity().getInterfaceMacAddress() != null)
			discovered.setMac(new String(device.getRoot().getIdentity()
					.getInterfaceMacAddress()));
		//Additional information
		putToHashMap(discovered.getTechoInfo(), "UUID", device.getIdentity()
				.getUdn().getIdentifierString());
		putToHashMap(discovered.getTechoInfo(), "Manufacturer", device
				.getDetails().getManufacturerDetails().getManufacturer());
		putToHashMap(discovered.getTechoInfo(), "Model Name", device.getDetails().getModelDetails().getModelName());
		putToHashMap(discovered.getTechoInfo(), "Serial", device.getDetails().getSerialNumber());
		return discovered;
	}

	public void run() {
		System.out.println("PassiveUpnp started");
		// TODO Auto-generated method stub
		// UPnP discovery is asynchronous, we need a callback
		RegistryListener listener = new RegistryListener() {

			public void remoteDeviceDiscoveryStarted(Registry registry,
					RemoteDevice device) {

			}

			public void remoteDeviceDiscoveryFailed(Registry registry,
					RemoteDevice device, Exception ex) {

			}

			public void remoteDeviceAdded(Registry registry, RemoteDevice device) {
				updateObservers(generate(device));
			}

			public void remoteDeviceUpdated(Registry registry,
					RemoteDevice device) {

			}

			public void remoteDeviceRemoved(Registry registry,
					RemoteDevice device) {

			}

			public void localDeviceAdded(Registry registry, LocalDevice device) {

			}

			public void localDeviceRemoved(Registry registry, LocalDevice device) {

			}

			public void beforeShutdown(Registry registry) {
				System.out
						.println("Before shutdown, the registry has devices: "
								+ registry.getDevices().size());
			}

			public void afterShutdown() {
				System.out.println("Shutdown of registry complete!");

			}
		};

		// This will create necessary network resources for UPnP right away
		System.out.println("Starting Cling...");
		UpnpService upnpService = new UpnpServiceImpl(listener);
		// Send a search message to all devices and services, they should
		// respond soon
		upnpService.getControlPoint().search(new STAllHeader(), 10);
	}

	@Override
	public ArrayList<String> broadcastDiscover() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ArrayList<String> discoverNetInt() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public HashMap<String, String> discoverType(ArrayList<String> discoveredIPs) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public HashMap<String, String> discoverConnection(ArrayList<String> inputIPs) {
		// TODO Auto-generated method stub
		return null;
	}

}
